package com.hp.bon.sgw.wh.channel.especial;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.StringUtils;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.wh.channel.auth.ServAuthService;
import com.hp.bon.sgw.wh.channel.common.BizConsts;
import com.hp.bon.sgw.wh.channel.common.BizParam;
import com.hp.bon.sgw.wh.channel.common.BizResult;
import com.hp.bon.sgw.wh.channel.outside.BizSlot;
import com.hp.bon.sgw.wh.channel.outside.*;
import com.hp.bon.sgw.wh.channel.outside.bizSlotOutQuery.utils.HttpClientUtils;
import com.hp.bon.sgw.wh.channel.outside.bizSlotOutQuery.utils.XmlMessageUtils;
import com.hp.bon.sgw.wh.service.UserResourceConfigService;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

public class SpecialApiBizProcedure {

    private static final Logger _log = LoggerFactory.getLogger(SpecialApiBizProcedure.class);

    // private UserResourceConfigService urcService;
    private SpecialApiConfigLoader specialApiConfigLoader;
    private SpecialApiBizRouter specialApiBizRouter;
    private SpecialApiResponsor specialApiResponsor;
    private ServAuthService servAuthService;
    private static SpecialApiBizProcedure outApiBizProcedure;

    public static SpecialApiBizProcedure instance() {
        if (null == outApiBizProcedure) {
            outApiBizProcedure = new SpecialApiBizProcedure();
            outApiBizProcedure.init();
        }
        return outApiBizProcedure;
    }

    private void init() {
        //
        specialApiConfigLoader = new SpecialApiConfigLoader();
        //
        specialApiBizRouter = new SpecialApiBizRouter();
        specialApiBizRouter.init();
        //
        specialApiResponsor = new SpecialApiResponsor();

        servAuthService = ServAuthService.instance();
    }

    public String doProcedure(XmlMessage xmlMessage, Request request, Response response, long startTime) {

        BizParam bizParam = new BizParam();

        // 读配置控制参数
        String areaCode = XmlMessageUtils.getAreaCode(xmlMessage);
        _log.info("/Service_Information/Area_Code={}", areaCode);
        String capability = XmlMessageUtils.getCapability(xmlMessage);
        bizParam.setParam(BizConsts.KEY_API_CAPABILITY, capability);
        _log.info("capability={}", capability);

        // 步骤1： 判断zw_falg 0走老流程,1走新流程
        int zw_flag = UserResourceConfigService.getIntValue("zw_flag", 0);
        if (zw_flag == 0) {
            // 走现在的流程和调用 (老流程)
            return BizConsts.TYPE_ORIG_FLOW;
        }

        // 步骤2.检查能力是否在新账务中心接口范围之内
        _log.info("SpecialApiCapabilities={}", SpecialApiCapabilities.listSpecialApiCapabilities());
        if (!SpecialApiCapabilities.hasCapability(capability)) {
            _log.info("capability={} use old flow", capability);
            return BizConsts.TYPE_ORIG_FLOW;
        }

        // 步骤： 调用鉴权接口
        String accNbr = HttpClientUtils.getXmlValue(xmlMessage, "/Service_Information/Acc_Nbr");
        BizParam authParam = new BizParam();
        authParam.setParam(BizConsts.KEY_ACC_NUM, areaCode+accNbr);
        authParam.setParam(BizConsts.KEY_OBJ_ATTR, "99");
        BizResult authResult = servAuthService.doAuthService(authParam);
        if (BizConsts.STATUS_ACOUNT_API_SUCCESS.equals(authResult.getCode())) {
            // 把认证成功以结果信息，填入bizParam
            String authBody = authResult.getHttpBody();
            @SuppressWarnings("unchecked")
            Map<String, Object> josnAuth = JSON.parseObject(authBody, Map.class);
            bizParam.setParam("acctId", String.valueOf(josnAuth.get("acctId")));
            bizParam.setParam("prodInstId", String.valueOf(josnAuth.get("prodInstId")));
            bizParam.setParam("areaCode", String.valueOf(josnAuth.get("areaCode")));
            bizParam.setParam("regionId", String.valueOf(josnAuth.get("regionId")));
            bizParam.setParam("paymentFlag", String.valueOf(josnAuth.get("paymentFlag")));
            //bizParam.setParam("statusCd", String.valueOf(josnAuth.get("statusCd")));
        } else {
            // 认证失败
            specialApiResponsor.doResponseError(response, "ServAuth fail");
            return BizConsts.TYPE_ERROR_FLOW;
        }


        // 步骤4. 加载配置信息
        bizParam = specialApiConfigLoader.doLoader(bizParam);

        // 步骤5.路由到对应的业务处理：BizSlot
        // doRouter不允许向外抛异常
        BizSlot bizSlot = specialApiBizRouter.doRouter(bizParam);
        if (null == bizSlot) {
            if (SpecialApiCapabilities.isWSCapability(capability)) {
                specialApiResponsor.doResponseWSError(response, xmlMessage.getMID(), 11009, "bizSlotRouterNone");
            } else if (SpecialApiCapabilities.isHttpCapability(capability)) {
                specialApiResponsor.doResponseStandardHttpError(response, "", "11104", "bizSlotRouterNone", "");
            } else {
                specialApiResponsor.doResponseError(response, "invalid request, bizSlot none.");
            }
            return BizConsts.TYPE_ERROR_FLOW;
        }

        // 步骤6：路由到请求对应的处理类：slot,做业务处理(调用新帐务中心接口)
        // doBiz不允许向外抛异常
        BizResult bizResult = bizSlot.doBiz(xmlMessage, bizParam);

        // 步骤7：记录请求日志信息
        //

        // 步骤8：响应外部
        // doResponse 不允许向外抛异常

        if (bizResult.getCode()!=null&&bizResult.getCode().equals(BizConsts.STATUS_ACOUNT_API_FAIL)) {
            specialApiResponsor.doResponseWSError(response,"",400,"Unknown error in request");
        }else{
            specialApiResponsor.doResponse(bizResult, response);
        }

        return BizConsts.TYPE_FINE_FLOW;
    }

}
